package com.bestcem.xm.om.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.util.StrUtil;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.om.dao.OmPrincipalDao;
import com.bestcem.xm.om.dao.OmUserDao;
import com.bestcem.xm.om.entity.OmPrincipal;
import com.bestcem.xm.om.entity.OmUser;
import com.bestcem.xm.om.enums.OmRoleTypeEnum;
import com.bestcem.xm.om.enums.OmUserStatusEnum;
import com.bestcem.xm.om.grpc.service.converter.OmUserConverter;
import com.bestcem.xm.om.grpc.v1.services.Principal;
import com.bestcem.xm.om.service.OmPrincipalService;
import com.bestcem.xm.om.service.dto.RelationDTO;
import com.bestcem.xm.om.service.dto.common.PageDTO;
import com.bestcem.xm.om.service.dto.principal.OmPrincipalDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 负责人相关的服务类
 *
 * @author xuan.yang <xuan.yang@idiaoyan.com>
 * @version v1.0
 * @date 2021/12/29 17:02
 */
@Slf4j
@Service
public class OmPrincipalServiceImpl implements OmPrincipalService {
    @Resource
    private OmPrincipalDao omPrincipalDao;
    @Resource
    private OmUserDao omUserDao;

    @Override
    public ServiceResult<RelationDTO> getOrgRelatedOp(String orgId) {
        if (!ObjectId.isValid(orgId)) {
            return ServiceResult.fail("组织名称不合法");
        }
        List<OmPrincipal> omPrincipals = omPrincipalDao.findByOrgId(orgId);
        if (CollUtil.isEmpty(omPrincipals)) {
            return ServiceResult.fail("查询信息为空");
        }
        RelationDTO relationDTO = new RelationDTO();
        List<String> idList = new ArrayList<>();
        omPrincipals.forEach(info -> {
            // 负责人
            if (OmRoleTypeEnum.SUPER_ADMIN.getIndex().equals(info.getType())) {
                relationDTO.setId(info.getOmUserId());
                relationDTO.setName(info.getName());
            } else if (OmRoleTypeEnum.COMMON_USER.getIndex().equals(info.getType())) {
                // 关联人
                idList.add(info.getOmUserId());
            }
        });
        if (!ObjectId.isValid(relationDTO.getId()) || StringUtils.isBlank(relationDTO.getName())) {
            log.error("[om]没有负责人，orgId为{}", orgId);
            return ServiceResult.fail("没有负责人信息");
        }
        if (CollUtil.isEmpty(idList)) {
            log.error("[om]没有关联人，orgId为{}", orgId);
            relationDTO.setRelationList(Collections.emptyList());
        } else {
            relationDTO.setRelationList(idList);
        }
        return ServiceResult.success(relationDTO);

    }

    @Override
    public List<RelationDTO> getOrgRelatedOp(List<String> orgIds) {
        List<OmPrincipal> omPrincipals = omPrincipalDao.listByOrgIds(orgIds);
        if (CollUtil.isEmpty(omPrincipals)) {
            return Collections.emptyList();
        }
        Map<String, List<OmPrincipal>> orgIdMap = omPrincipals.stream().collect(Collectors.groupingBy(OmPrincipal::getOrgId));
        List<RelationDTO> relationDTOList = new ArrayList<>();
        for (Map.Entry<String, List<OmPrincipal>> entry : orgIdMap.entrySet()) {
            List<OmPrincipal> principals = entry.getValue();
            com.bestcem.xm.om.service.dto.RelationDTO relationDTO = new RelationDTO();
            relationDTO.setOrgId(entry.getKey());
            List<String> idList = new ArrayList<>();
            // 有一个负责人，多个关联人
            for (OmPrincipal principal : principals) {
                if (OmRoleTypeEnum.SUPER_ADMIN.getIndex().equals(principal.getType())) {
                    relationDTO.setId(principal.getOmUserId());
                    relationDTO.setName(principal.getName());
                } else if (OmRoleTypeEnum.COMMON_USER.getIndex().equals(principal.getType())) {
                    // 关联人
                    idList.add(principal.getOmUserId());
                }
            }
            relationDTO.setRelationList(idList);
            relationDTOList.add(relationDTO);
        }
        return relationDTOList;
    }

    @Override
    public ServiceResult<List<String>> listIdsByName(String name) {
        if (StrUtil.isBlank(name)) {
            return ServiceResult.fail("名称为空");
        }
        List<OmPrincipal> omPrincipals = omPrincipalDao.findByName(name);
        if (CollUtil.isEmpty(omPrincipals)) {
            return ServiceResult.success(Collections.emptyList());
        }
        List<String> returnList = new ArrayList<>();
        omPrincipals.forEach(info -> {
            if (!returnList.contains(info.getOrgId())) {
                returnList.add(info.getOrgId());
            }
        });
        return ServiceResult.success(returnList);
    }

    @Override
    public ServiceResult<Void> createOrgRelatedOp(String orgId, String principalOp, List<String> relates) {
        return insertOrgRelatedOp(orgId, principalOp, relates);
    }

    @Override
    public ServiceResult<Void> updateOrgRelatedOp(String orgId, String principalOp, List<String> relates) {
        // 先根据orgid删除，然后再新增
        omPrincipalDao.removeByOrgId(orgId);
        return insertOrgRelatedOp(orgId, principalOp, relates);
    }

    @Override
    public ServiceResult<List<com.bestcem.xm.om.grpc.v1.services.OmPrincipal>> listOmPrincipals(OmPrincipal principal) {
        List<OmPrincipal> omPrincipals = omPrincipalDao.listByCondition(principal);
        if (CollUtil.isEmpty(omPrincipals)) {
            return ServiceResult.fail("查询信息为空");
        }
        List<com.bestcem.xm.om.grpc.v1.services.OmPrincipal> grpcPrincipals = omPrincipals.stream().map(OmUserConverter::convertToGrpcPrincipal).collect(Collectors.toList());
        return ServiceResult.success(grpcPrincipals);
    }

    @Override
    public PageDTO<Principal> pageByOrgIds(Set<String> orgIds, Integer currentPage, Integer size) {
        Long count = omPrincipalDao.countPrincipalByOrgIds(orgIds);
        PageDTO<Principal> pageDTO = new PageDTO<>();
        pageDTO.setTotal(Math.toIntExact(count));
        // 为空不需要再次查询
        if (count == 0) {
            pageDTO.setData(Collections.emptyList());
            return pageDTO;
        }
        List<OmPrincipal> omPrincipals = omPrincipalDao.pageByOrgIds(orgIds, currentPage, size);
        if (ObjectUtils.isNotEmpty(omPrincipals)) {
            List<Principal> principals = convertToGrpcPrincipal(omPrincipals);
            pageDTO.setData(principals);
        } else {
            pageDTO.setData(Collections.emptyList());
        }
        // 说明此时分页过大
        return pageDTO;
    }

    @Override
    public ServiceResult<OmPrincipalDTO> listOmPrincipalsByOrgId(String orgId) {
        List<OmPrincipal> principals = omPrincipalDao.findByOrgId(orgId);
        if (CollectionUtils.isEmpty(principals)) {
            return ServiceResult.success();
        }
        // 有一个负责人，多个关联人
        OmPrincipalDTO omPrincipalDTO = new OmPrincipalDTO();
        List<OmPrincipal> relatedList = new ArrayList<>();
        for (OmPrincipal principal : principals) {
            if (OmRoleTypeEnum.SUPER_ADMIN.getIndex().equals(principal.getType())) {
                omPrincipalDTO.setPrincipal(principal);
            } else if (OmRoleTypeEnum.COMMON_USER.getIndex().equals(principal.getType())) {
                // 关联人
                relatedList.add(principal);
            }
        }
        omPrincipalDTO.setRelatedList(relatedList);
        return ServiceResult.success(omPrincipalDTO);
    }

    private List<Principal> convertToGrpcPrincipal(List<OmPrincipal> omPrincipals) {
        return omPrincipals.stream()
                .map(info -> Principal.newBuilder()
                        .setOrgId(info.getOrgId())
                        .setId(info.getOmUserId())
                        .setName(info.getName())
                        .build()).collect(Collectors.toList());
    }

    private ServiceResult<Void> insertOrgRelatedOp(String orgId, String principalOp, List<String> relates) {
        if (ObjectId.isValid(orgId)) {
            if (StringUtils.isBlank(principalOp) && CollectionUtils.isEmpty(relates)) {
                return ServiceResult.fail("传入负责人或关联人");
            }
            if (StrUtil.isNotBlank(principalOp)) {
                OmUser omUser = omUserDao.findByIdAndStatus(principalOp, OmUserStatusEnum.ENABLE.getIndex());
                if (Objects.isNull(omUser)) {
                    return ServiceResult.fail("关联人不存在");
                }
                OmPrincipal omPrincipal = new OmPrincipal();
                omPrincipal.setOrgId(orgId);
                omPrincipal.setOmUserId(principalOp);
                omPrincipal.setType(OmRoleTypeEnum.SUPER_ADMIN.getIndex());
                omPrincipal.setName(omUser.getRealName());
                omPrincipal.setUserName(omUser.getUsername());
                omPrincipal.setCreateTime(LocalDateTime.now());
                omPrincipal.setUpdateTime(omPrincipal.getCreateTime());
                omPrincipalDao.save(omPrincipal);
            }
            if (!CollectionUtils.isEmpty(relates)) {
                List<OmUser> users = omUserDao.listByIdsAndStatus(relates, OmUserStatusEnum.ENABLE.getIndex());
                List<OmPrincipal> principals = new ArrayList<>();
                users.forEach(user -> {
                    OmPrincipal omPrincipal = new OmPrincipal();
                    omPrincipal.setOrgId(orgId);
                    omPrincipal.setOmUserId(user.getId());
                    omPrincipal.setType(OmRoleTypeEnum.COMMON_USER.getIndex());
                    omPrincipal.setName(user.getRealName());
                    omPrincipal.setUserName(user.getUsername());
                    omPrincipal.setCreateTime(LocalDateTime.now());
                    omPrincipal.setUpdateTime(omPrincipal.getCreateTime());
                    principals.add(omPrincipal);
                });
                if (log.isInfoEnabled()) {
                    log.info("[om]获取到的操作列表数目为{}", principals.size());
                }
                if (!CollectionUtils.isEmpty(principals)) {
                    omPrincipalDao.batchInsert(principals);
                }
            }
            return ServiceResult.success();
        } else {
            return ServiceResult.fail("公司id不正确");
        }

    }
}
